# app/ui/main_window.py - 主窗口UI类
import cv2
from PySide6.QtWidgets import QMainWindow, QWidget, QHBoxLayout, QVBoxLayout
from PySide6.QtCore import Qt, QTimer
import os
import time  # 添加在文件开头的导入部分

from app.ui.components import VideoPanel, ControlPanel
from app.detection import ObjectDetector
from app.config import DEFAULT_REGION, DEFAULT_MODEL_PATH, DEFAULT_CONF
from app.audio.tts import TextToSpeech
from .components.ip_dialog import IPInputDialog
from .components.control_info_panel import ControlInfoPanel
from app.input.joystick import JoystickManager  # 确保这行存在

class ObjectDetectionWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        print("初始化主窗口...")  # 添加这行
        self.setWindowTitle("物体检测计数器")
        self.setGeometry(100, 100, 1200, 800)

        # 初始化语音引擎
        self.tts_engine = TextToSpeech()

        # 初始化变量
        self.video_path = None
        self.cap = None
        self.is_processing = False
        self.timer = QTimer()
        self.timer.timeout.connect(self._process_frame)
        
        # 初始化检测器
        self.detector = ObjectDetector(
            region_points=DEFAULT_REGION,
            model_path=DEFAULT_MODEL_PATH,
            conf=DEFAULT_CONF
        )
        
        # 初始化语音播报定时器
        self.speech_timer = QTimer()
        self.speech_timer.timeout.connect(self.speak_results)

        # 创建UI组件
        self._setup_ui()
        
        # 连接信号和槽
        self._connect_signals()
        
        print("正在初始化手柄管理器...")  # 添加这行
        # 初始化手柄管理器
        self.joystick_manager = JoystickManager()
        
        print("尝试连接手柄...")  # 添加这行
        # 尝试连接手柄
        if self.joystick_manager.connect():
            self.joystick_manager.start_polling(self._on_joystick_update)
            self.video_panel.set_status_message("已连接手柄")
            print("手柄已连接并开始轮询")
        else:
            self.video_panel.set_status_message("未检测到手柄")
            print("未检测到手柄")
        
    def _setup_ui(self):
        # 创建主窗口部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局，使用水平布局放置主视频区域和控制信息区域
        main_horizontal_layout = QHBoxLayout(central_widget)
        main_horizontal_layout.setContentsMargins(5, 5, 5, 5)  # 减小边距
        
        # 主视频和控制区域容器
        main_content_widget = QWidget()
        main_layout = QVBoxLayout(main_content_widget)
        main_layout.setContentsMargins(0, 0, 0, 0)  # 移除内边距
        main_layout.setSpacing(5)  # 减小组件间距
        
        # 创建视频面板
        self.video_panel = VideoPanel()
        main_layout.addWidget(self.video_panel, 95)  # 分配95%的垂直空间给视频区域
        
        # 创建控制面板
        self.control_panel = ControlPanel(self.tts_engine)
        main_layout.addWidget(self.control_panel, 5)  # 只分配5%的垂直空间给控制面板
        
        # 创建控制信息面板
        self.control_info_panel = ControlInfoPanel()
        
        # 添加主内容区域和控制信息区域到水平布局
        main_horizontal_layout.addWidget(main_content_widget, 9)  # 分配90%的空间
        main_horizontal_layout.addWidget(self.control_info_panel, 1)     # 分配10%的空间
        
    def _connect_signals(self):
        """连接所有信号和槽"""
        self.control_panel.start_button.clicked.connect(self.toggle_processing)
        self.control_panel.tts_button.clicked.connect(self.speak_results)
        self.control_panel.auto_speech_button.clicked.connect(self.toggle_auto_speech)
        self.control_panel.connect_raspberry_button.clicked.connect(self.connect_raspberry_pi)
        
    def toggle_auto_speech(self):
        """切换自动语音播报功能"""
        self.auto_speech_enabled = self.control_panel.toggle_auto_speech()
        
        if self.auto_speech_enabled:
            # 启动定时器，每5秒播报一次
            if self.is_processing:
                self.speech_timer.start(5000)  # 5000毫秒 = 5秒
        else:
            # 停止定时器
            self.speech_timer.stop()
    
    def toggle_processing(self):
        if not self.is_processing:
            # 检查视频捕获对象是否有效
            if not self.cap or not self.cap.isOpened():
                self.video_panel.set_status_message("视频流未就绪")
                return
                
            # 开始处理
            self.is_processing = True
            self.control_panel.update_start_button(True)
            self.timer.start(30)  # 30ms 刷新率
            
            # 如果自动播报已启用，开始定时播报
            if self.auto_speech_enabled:
                self.speech_timer.start(5000)  # 5000毫秒 = 5秒
        else:
            # 停止处理
            self.timer.stop()
            self.is_processing = False
            self.control_panel.update_start_button(False)
            
            # 停止定时播报，但保持自动播报状态
            self.speech_timer.stop()
    
    def _process_frame(self):
        if self.cap and self.is_processing:
            try:
                success, frame = self.cap.read()
                if not success:
                    self.video_panel.set_status_message("无法读取视频帧")
                    return
                
                # 使用检测器处理帧
                stats_frame, total_objects, class_counts = self.detector.process_frame(frame)
                
                # 显示处理后的帧和更新统计信息
                self.video_panel.display_frame(stats_frame)
                self.video_panel.update_stats(total_objects, class_counts)
                
            except Exception as e:
                self.video_panel.set_status_message(f"处理视频帧时发生错误: {str(e)}")
                if self.cap:
                    self.cap.release()
                self.toggle_processing()  # 停止处理

    def speak_results(self):
        '''语音播报检测结果'''
        if not self.tts_engine.is_available():
            from PySide6.QtWidgets import QMessageBox
            QMessageBox.warning(self, "语音引擎不可用", "请确保已安装pyttsx3库。\n"
                              "可以通过运行 'pip install pyttsx3'安装。")
            return
    
        # 构建要播报的文本
        if hasattr(self, 'detector') and hasattr(self.detector, 'unique_object_ids'):
            total_objects = len(self.detector.unique_object_ids)
        
            speak_text = f"区域内共检测到{total_objects}个物体。"
        
            # 添加各类别数量信息
            if hasattr(self.detector, 'class_counts') and self.detector.class_counts:
                for class_name, count in sorted(
                    self.detector.class_counts.items(), 
                    key=lambda x: x[1], 
                    reverse=True
                )[:3]:  # 只报告前三个最多的类别
                    if count > 0:
                        speak_text += f"其中{class_name}{count}个。"
        
            # 播放语音
            self.tts_engine.speak(speak_text)
            
    def closeEvent(self, event):
        # 程序关闭时释放资源
        if self.cap:
            self.cap.release()
        
        # 停止所有定时器
        self.timer.stop()
        self.speech_timer.stop()
        
        event.accept()

    def connect_raspberry_pi(self):
        """连接树莓派并获取视频流"""
        dialog = IPInputDialog(self)
        if dialog.exec():
            ip_address = dialog.get_ip_address()
            port = dialog.get_port()
            
            if ip_address and port:
                try:
                    # 使用HTTP流地址
                    http_url = f"http://{ip_address}:{port}/video_feed"
                    
                    # 设置OpenCV的FFMPEG参数
                    self.cap = cv2.VideoCapture(http_url, cv2.CAP_FFMPEG)
                    
                    # 设置FFMPEG参数
                    self.cap.set(cv2.CAP_PROP_BUFFERSIZE, 3)
                    # 设置超时时间（毫秒）
                    self.cap.set(cv2.CAP_PROP_OPEN_TIMEOUT_MSEC, 10000)  # 10秒连接超时
                    self.cap.set(cv2.CAP_PROP_READ_TIMEOUT_MSEC, 10000)  # 10秒读取超时
                    
                    # 尝试读取一帧来验证连接
                    ret, frame = self.cap.read()
                    if ret:
                        self.video_path = http_url
                        self.control_panel.start_button.setEnabled(True)
                        self.video_panel.set_status_message(f"已连接到视频服务器: {ip_address}:{port}")
                        # 初始化检测器
                        self.detector.initialize()
                    else:
                        self.video_panel.set_status_message("无法读取视频流")
                        if self.cap:
                            self.cap.release()
                            self.cap = None
                except Exception as e:
                    self.video_panel.set_status_message(f"连接失败: {str(e)}")
                    if self.cap:
                        self.cap.release()
                        self.cap = None

    def _on_joystick_update(self, left_x, left_y, right_x, right_y):
        """处理手柄摇杆更新"""
        # 更新UI显示
        self.control_info_panel.update_joystick_info(left_x, left_y, right_x, right_y)
        
        # 打印调试信息（每秒最多打印一次）
        if not hasattr(self, '_last_print_time'):
            self._last_print_time = 0
        current_time = time.time()
        if current_time - self._last_print_time >= 1.0:  # 每秒打印一次
            print(f"手柄数据 - 左摇杆: ({left_x:.2f}, {left_y:.2f}), 右摇杆: ({right_x:.2f}, {right_y:.2f})")
            self._last_print_time = current_time